import { endRecording, startRecording } from '@/services/broadcast';
import {
  add_platform_chatLog,
  edit_platform_chatLog,
  get_platform_guidance_info,
  guidance_Token,
  platform_chat_call,
  platform_guidance_patients,
  submit_platform_guidance,
} from '@/services/guide';
import age from '@/utils/age';
import { random_int } from '@/utils/randomstring';
import { PageContainer, ProDescriptions, ProTable } from '@ant-design/pro-components';
import AgoraRTC from 'agora-rtc-sdk-ng';
import AgoraRTM from 'agora-rtm-sdk';
import { Button, Card, Divider, message, Modal } from 'antd';
import TextArea from 'antd/es/input/TextArea';
import moment from 'moment';
import { useEffect, useRef, useState } from 'react';
import './index.less';

var RTCclient: any;
var RTMclient: any;
var RTMchannel: any;
var my_uuid = '';
var to_uuid = '';
var channel = '';
var rtcToken = '';
var rtmToken = '';
//呼叫记录id
var chatlog_id = '';
var sid = '';
var resourceId = '';
// 录制随机uid
var record_uuid = random_int(7).toString();
var start_time = '';
// 指导内容
var chat_content = '';
// 下次指导时间
var chat_time = moment(moment().day(moment().day() + 7)).format('YYYY-MM-DD');
// 下次指导备注
var remark = '';

// 用来放置本地音视频频轨道对象
var localAudioTrack: any;
var localVideoTrack: any;
const options = {
  appId: '268a993cd77249cf9f3c1e09a279e96c',
};
const videoConfig: any = {
  // 预设分辨率 默认 480p_1
  encoderConfig: '720p_1',
};
// 存储机构id
var platform_id: number | undefined = undefined
const RemoteVideo = () => {
  // 获取URL参数
  const getUrlParam = (name: string) => {
    const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
    const r = window.location.search.substring(1).match(reg);
    if (r != null) {
      return decodeURIComponent(r[2]);
    }
    return null;
  };
  // 存储当前指导id
  const guideId: any = getUrlParam('id');
  // 存储患者id
  const patientId: any = getUrlParam('patient_id');
  // 存储指导详情
  const [guideInfo, setGuideInfo] = useState<any>(undefined);
  // 倒计时秒 和 定时器
  const [times, settimes] = useState<any>(60);
  const timer: any = useRef();
  // 通话计时 和 计时器
  const [second, setsecond] = useState(0);
  const timemeter: any = useRef();
  const chatlog_second = useRef(second);
  chatlog_second.current = second;
  // 接听状态 用来处理 true显示拨打中倒计时/false显示已接通
  const [LocalInvitation, setLocalInvitation] = useState(true);
  // 取消呼叫loading状态
  const [cancelloading, setcancelloading] = useState(false);
  // 重新拨打loading状态
  const [callloading, setcallloading] = useState(false);
  // 通话状态 0未开始 1呼叫中 2通话中
  const [callstatus, setcallstatus] = useState(0);
  const call = useRef(callstatus);
  call.current = callstatus;

  useEffect(() => {
    //d登录rtm
    // console.log('123----------------------------', times, timer, second, timemeter, chatlog_second);
    async function rtmLogin() {
      let request_body = {
        id: Number(guideId),
        type: 2,
      };
      let res: any = await guidance_Token(request_body);
      console.log('指导频道和token', res);
      if (res.msg == 'ok') {
        console.log('to_uuid123456789', res.data.uuid);
        RTMclient = AgoraRTM.createInstance(options.appId);
        await RTMclient.login({ uid: res.data.uuid.toString(), token: res.data.rtmtoken });
        // RTMchannel = RTMclient.createChannel(channel);
        // await RTMchannel.join();
        // 点对点消息，用来处理连麦生命周期 ， 接收挂断通知
        RTMclient.on('MessageFromPeer', async (message_n: any, peerId: number) => {
          console.log('message ', message_n, ' peerId', peerId);
          // 对方接受呼叫邀请
          if (
            message_n.messageType === 'TEXT' &&
            JSON.parse(message_n.text).type == 'video_LocalInvitationAccepted' &&
            peerId == res.data.to_uuid
          ) {
            // 清除定时器
            clearInterval(timer.current);
            // 开始通话倒计时
            start_second();
            // 接听状态改为已接听
            setLocalInvitation(false);
            //修改呼叫状态为呼叫中
            setcallstatus(1);
            // 修改呼叫记录（通话中）
            edit_chatlog(1);
            // 开始录制
            start_recording(channel);
            //修改通话状态(2通话中)
            setcallstatus(2);
            message.warning('对方已接受呼叫邀请');
          }
          // 对方已拒绝呼叫邀请
          if (
            message_n.messageType === 'TEXT' &&
            JSON.parse(message_n.text).type == 'video_LocalInvitationRefused' &&
            peerId == res.data.to_uuid
          ) {
            console.log('message ' + message_n.text + ' peerId' + peerId);
            // 修改取消呼叫loading状态
            setcancelloading(true);
            // 取消推流
            leave_Live('', 'reject');
            // 修改呼叫记录（已拒绝）
            edit_chatlog(2);
            //修改通话状态 (0未开始)
            setcallstatus(0);
            message.warning('对方已拒绝呼叫邀请');
          }
          // 对方取消视频通话
          if (
            message_n.messageType === 'TEXT' &&
            JSON.parse(message_n.text).type == 'end_video_fNFMEI1B' &&
            peerId == res.data.to_uuid
          ) {
            console.log('message ' + message_n.text + ' peerId' + peerId);
            // 修改取消呼叫loading状态
            setcancelloading(true);
            // 取消推流
            await leave_Live('end', 'reject');
            // edit_chatlog(3);
            setsecond(0);
            //通话状态 0未开始
            setcallstatus(0);
            message.warning('对方已取消通话');
          }
        });
      }
    }
    rtmLogin();
  }, []);
  // 获取指导详情
  useEffect(() => {
    const get_guide_info = async () => {
      let res: any = await get_platform_guidance_info({ id: guideId });
      console.log('指导详情', res);
      if (res.code == 200) {
        setGuideInfo(res.data);
        platform_id = res.data.platform_id
      }
    };
    get_guide_info().then(() => {
      Modal.warning({
        title: '温馨提示：',
        content: '为了维护您的合法权益，平台将自动录制视频指导的全过程',
        closable: true,
        centered: true,
      });
      start_guide();
    });

  }, []);

  // 监听页面刷新或关闭
  useEffect(() => {
    window.addEventListener('beforeunload', leave_Live_error);
    return () => {
      window.removeEventListener('beforeunload', leave_Live_error);
    };
  }, []);
  // 开始指导
  const start_guide = async () => {
    if (guideId) {
      let request_body = {
        id: Number(guideId),
        type: 2,
      };
      let res: any = await guidance_Token(request_body);
      console.log('指导频道和token', res);
      if (res.msg == 'ok') {
        chat_call(0);
        channel = res.data.channel;
        my_uuid = res.data.uuid;
        to_uuid = res.data.to_uuid;
        rtcToken = res.data.rtctoken;
        rtmToken = res.data.rtmtoken;
        RTCclient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' });
        RTCclient.setClientRole('host');
        //   监听用户推流
        RTCclient.on('user-published', async (user: any, mediaType: any) => {
          await RTCclient.subscribe(user, mediaType);
          console.log('user-published', user, mediaType);
          if (mediaType == 'video') {
            // 订阅完成后，从 `user` 中获取远端视频轨道对象
            const remoteVideoTrack = user.videoTrack;
            // 动态插入一个 DIV 节点作为播放远端视频轨道的容器
            // playerContainer = document.getElementById('audience');
            // 订阅完成，播放远端音视频
            // 传入 DIV 节点，让 SDK 在这个节点下创建相应的播放器播放远端视频
            remoteVideoTrack.play(document.getElementById('audience'), {
              mirror: false,
              fit: 'contain',
            });
          }
          if (mediaType == 'audio') {
            // 订阅完成后，从 `user` 中获取远端音频轨道对象
            const remoteAudioTrack = user.audioTrack;
            // 播放音频因为不会有画面，不需要提供 DOM 元素的信息
            remoteAudioTrack.play();
          }
        });
        //   监听用户取消推流
        RTCclient.on('user-unpublished', async (user: any, mediaType: any) => {
          console.log('user-unpublished', user, mediaType);
          // 远端用户取消发布或离开频道
        });
        RTCclient.join(options.appId, res.data.channel, res.data.rtctoken, res.data.uuid).then(
          async () => {
            localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
            localVideoTrack = await AgoraRTC.createCameraVideoTrack(videoConfig);
            // console.log('RtcHHHHHHHHHHHHHHHHHHHHHHHH', RTCclient);

            await RTCclient.publish([localAudioTrack, localVideoTrack]);
            localVideoTrack.play(document.getElementById('host'), {
              mirror: false,
              fit: 'contain',
            });
          },
        );
        // 加入频道
        // join(res.data.uuid, res.data.rtmtoken, res.data.channel, res.data.to_uuid);
      } else {
        message.error(res.msg);
      }
    }
  };
  // 加入RTM频道
  const join = async (uuid: number, rtmtoken: string, channel: string, to_uuid: number) => {
    // console.log('to_uuid123456789', to_uuid);
    // RTMclient = AgoraRTM.createInstance(options.appId);
    // await RTMclient.login({ uid: uuid.toString(), token: rtmtoken });
    // RTMchannel = RTMclient.createChannel(channel);
    // await RTMchannel.join();
    // // 点对点消息，用来处理连麦生命周期 ， 接收挂断通知
    // RTMclient.on('MessageFromPeer', async (message_n: any, peerId: number) => {
    //   console.log('message ', message_n, ' peerId', peerId);
    //   // 对方接受呼叫邀请
    //   if (
    //     message_n.messageType === 'TEXT' &&
    //     JSON.parse(message_n.text).type == 'video_LocalInvitationAccepted' &&
    //     peerId == to_uuid
    //   ) {
    //     // 清除定时器
    //     clearInterval(timer.current);
    //     // 开始通话倒计时
    //     start_second();
    //     // 接听状态改为已接听
    //     setLocalInvitation(false);
    //     //修改呼叫状态为呼叫中
    //     setcallstatus(1);
    //     // 修改呼叫记录（通话中）
    //     edit_chatlog(1);
    //     // 开始录制
    //     start_recording(channel);
    //     //修改通话状态(2通话中)
    //     setcallstatus(2);
    //     message.warning('对方已接受呼叫邀请');
    //   }
    //   // 对方已拒绝呼叫邀请
    //   if (
    //     message_n.messageType === 'TEXT' &&
    //     JSON.parse(message_n.text).type == 'video_LocalInvitationRefused' &&
    //     peerId == to_uuid
    //   ) {
    //     console.log('message ' + message_n.text + ' peerId' + peerId);
    //     // 修改取消呼叫loading状态
    //     setcancelloading(true);
    //     // 取消推流
    //     leave_Live('', 'reject');
    //     // 修改呼叫记录（已拒绝）
    //     edit_chatlog(2);
    //     //修改通话状态 (0未开始)
    //     setcallstatus(0);
    //     message.warning('对方已拒绝呼叫邀请');
    //   }
    //   // 对方取消视频通话
    //   if (
    //     message_n.messageType === 'TEXT' &&
    //     JSON.parse(message_n.text).type == 'end_video_fNFMEI1B' &&
    //     peerId == to_uuid
    //   ) {
    //     console.log('message ' + message_n.text + ' peerId' + peerId);
    //     // 修改取消呼叫loading状态
    //     setcancelloading(true);
    //     // 取消推流
    //     await leave_Live('end', 'reject');
    //     // edit_chatlog(3);
    //     setsecond(0);
    //     //通话状态 0未开始
    //     setcallstatus(0);
    //     message.warning('对方已取消通话');
    //   }
    // });
    // chat_call(0);
  };
  // 极光呼叫
  const chat_call = async (status: number) => {

    // 接通倒计时
    start_times();
    let request_body = {
      id: Number(guideId),
      status,
      platform_id: Number(platform_id),
    };
    let res: any = await platform_chat_call(request_body);
    console.log('极光呼叫', res);
    if (res.msg == 'ok') {
      // 新增一条呼叫记录
      let request_body = {
        platform_guidance_id: guideId,
      };
      let params: any = await add_platform_chatLog(request_body);
      if (params.msg == 'ok') {
        //设置当前呼叫logid
        chatlog_id = params.data.id;
        //修改呼叫状态为呼叫中
        setcallstatus(1);
      }
    } else {
      message.error(res.msg);
    }
    setcallloading(false);
  };
  const error_edit_chatlog = (status: number) => {
    if (chatlog_id) {
      let request_body = {
        id: chatlog_id,
        status: status,
        time: chatlog_second.current,
      };
      edit_platform_chatLog(request_body);
    }
  };
  //关闭页面 异常退出挂断
  const leave_Live_error = () => {
    if (call.current == 1) {
      error_edit_chatlog(4);
    }
    if (call.current == 2) {
      error_edit_chatlog(3);
      // 结束录制
      end_recording();
    }
    RTMclient.sendMessageToPeer(
      { text: JSON.stringify({ type: 'end_video_fNFMEI1B' }) },
      to_uuid.toString(),
    );
    window.opener.postMessage('remoteRefresh', '*');

    RTCclient = null;
  };
  // 挂断
  const leave_Live = async (type?: string, status?: string) => {
    //退出RTC RTM 关闭页面
    if (status != 'reject') {
      RTMclient.sendMessageToPeer(
        { text: JSON.stringify({ type: 'end_video_fNFMEI1B' }) },
        to_uuid.toString(),
      );
    }
    if (type == 'end') {
      edit_chatlog(3);
      // 结束录制
      end_recording();
    }
    if (type == 'quit') {
      edit_chatlog(4);
    }
    window.opener.postMessage('remoteRefresh', '*');
    // 清除定时器
    clearInterval(timer.current);
    // 重置
    settimes(60);
    // 接听状态 显示拨打中倒计时
    setLocalInvitation(true);

    // 清除延时器
    clearInterval(timemeter.current);

    // RTMclient.logout();
    if (localAudioTrack) {
      localAudioTrack.close();
    }
    if (localVideoTrack) {
      localVideoTrack.close();
    }
    if (RTCclient) {
      await RTCclient.unpublish();
    }
    // 离开频道。
    await RTCclient.leave();
    RTCclient = null;

    //修改呼叫状态为未开始
    setcallstatus(0);
    setcancelloading(false);
  };

  //修改当前呼叫状态
  const edit_chatlog = (status: number) => {
    if (chatlog_id) {
      let request_body = {
        id: chatlog_id,
        status: status,
        time: chatlog_second.current,
      };
      edit_platform_chatLog(request_body);
    }
  };

  // 开始录制按钮回调
  const start_recording = async (channel: string) => {
    let request_body = {
      id: guideId,
      cname: channel,
      uid: record_uuid,
      type: 2,
      fileNamePrefix: process.env.UMI_ENV,
      mixedVideoLayout:1,
    };
    let params: any = await startRecording(request_body);
    console.log('开始录制', params);
    if (params.msg == 'ok') {
      sid = params.data.sid;
      resourceId = params.data.resourceId;
      start_time = moment().format('YYYY-MM-DD HH:mm:ss');
    }
  };

  // 结束录制按钮回调
  const end_recording = async () => {
    let request_body = {
      cname: channel,
      uid: record_uuid,
      resourceId,
      sid,
      object_id: guideId,
      start_time,
      end_time: moment().format('YYYY-MM-DD HH:mm:ss'),
    };
    let params: any = await endRecording(request_body);
    console.log('结束录制', params);
  };

  //修改指导记录
  const onChangecontent = (e: { target: { value: string } }) => {
    chat_content = e.target.value;
  };

  // 结束指导
  const end_guide = async () => {
    if (chat_content.replace(/^\s\s*/, '').replace(/\s\s*$/, '') == '') {
      message.warning('请填写指导记录');
      return;
    }
    let request_body = {
      id: guideId,
      content: chat_content,
    };
    let res: any = await submit_platform_guidance(request_body);
    if (res.msg == 'ok') {
      message.success('指导已结束');
      window.opener.postMessage('remoteClose', '*');
      setTimeout(() => {
        window.close();
      }, 500);
    } else {
      message.error(res.msg);
    }
  };

  // 获取预约列表
  const get_invite_list = async () => {
    if (guideId) {
      let res: any = await platform_guidance_patients({ id: guideId });
      console.log('患者列表', res);
      return {
        data: res.data,
        success: true,
        total: res.data.length,
      };
    }
  };
  //接通倒计时
  const start_times = () => {
    console.log('接通倒计时');
    clearInterval(timer.current);
    timer.current = setInterval(() => {
      settimes((times: number) => {
        if (times > 0) {
          return times - 1;
        } else if (times == 0) {
          leave_Live();
          setcallstatus(0);
          return 60;
        }
      });
    }, 1000);
  };

  //通话计时
  const start_second = () => {
    console.log('开始通话计时');
    clearInterval(timemeter.current);
    timemeter.current = setInterval(() => {
      setsecond((second) => {
        return second + 1;
      });
    }, 1000);
  };

  //计时器格式化
  const studyTime = (t: number) => {
    let hour: any = Math.floor(t / 60 / 60);
    let minute: any = Math.floor((t / 60) % 60);
    let second: any = Math.floor(t % 60);
    if (hour < 10) {
      hour = '0' + hour;
    }
    if (minute < 10) {
      minute = '0' + minute;
    }
    if (second < 10) {
      second = '0' + second;
    }
    return hour + ':' + minute + ':' + second;
  };
  // 预约列表字段
  const invite_columns: any = [
    {
      title: '序号',
      align: 'center',
      dataIndex: 'index',
      valueType: 'index',
    },
    {
      title: '患者账号',
      align: 'center',
      dataIndex: 'patient_phone',
      key: 'patient_phone',
    },
    {
      title: '患者姓名',
      align: 'center',
      dataIndex: 'patient_name',
      key: 'patient_name',
    },
    {
      title: '性别',
      key: 'patient_sex',
      dataIndex: 'patient_sex',
      valueType: 'select',
      valueEnum: {
        0: {
          text: '未知',
        },
        1: {
          text: '男',
        },
        2: {
          text: '女',
        },
      },
    },
    {
      title: '年龄',
      align: 'center',
      dataIndex: 'patient_birth',
      key: 'patient_birth',
      render: (_: any, record: any) => age(record.patient_birth),
    },
  ];
  return (
    <PageContainer
      breadcrumb={false}
      header={{
        title: '视频指导',
        extra: [
          <Button key="end" type="primary" onClick={() => end_guide()} disabled={!LocalInvitation}>
            结束指导
          </Button>,
          <Button
            key="exit"
            onClick={() => {
              window.opener.postMessage('remoteRefresh', '*');
              window.close();
            }}
          >
            返回
          </Button>,
        ],
      }}
    >
      <Divider />
      {guideInfo === undefined ? (
        ''
      ) : (
        <>
          <Card>
            <ProDescriptions
              dataSource={guideInfo}
              column={4}
              columns={[
                {
                  title: '机构名称',
                  key: 'platform_name',
                  dataIndex: 'platform_name',
                },
                {
                  title: '预约账号',
                  key: 'platform_phone',
                  dataIndex: 'platform_phone',
                },
                {
                  title: '计划指导时间',
                  dataIndex: 'plan_time',
                  hideInSearch: true,
                },
                {
                  title: '备注',
                  key: 'remark',
                  dataIndex: 'remark',
                },
              ]}
            ></ProDescriptions>
          </Card>
          <div
            className="call_box_video"
            id="call_box_video"
            style={{ width: '100%', display: 'flex', margin: '0 auto', marginTop: '30px' }}
          >
            <div id="left_box" style={{ flex: 3 }}>
              <div id="host"></div>
              <div id="audience"></div>
              {LocalInvitation ? (
                callstatus == 1 ? (
                  <div className="call_text">
                    <p style={{ marginTop: '20%', color: '#929292' }}>等待对方接听······</p>
                    {times <= 55 ? (
                      <Button
                        type="primary"
                        danger
                        onClick={() => {
                          setcancelloading(true);
                          leave_Live('quit');
                        }}
                        loading={cancelloading}
                      >
                        取消呼叫
                      </Button>
                    ) : (
                      <></>
                    )}
                    <p style={{ marginTop: '20px', color: '#929292' }}>{times < 0 ? 0 : times} s</p>
                  </div>
                ) : (
                  <div className="call_text">
                    <p style={{ marginTop: '20%', color: '#929292' }}>已取消通话</p>

                    <Button
                      type="primary"
                      danger
                      onClick={() => {
                        setcallloading(true);
                        start_guide();
                      }}
                      loading={callloading}
                    >
                      重新拨打
                    </Button>
                  </div>
                )
              ) : (
                <div className="callend_text">
                  <p style={{ marginTop: '20px', color: '#fff' }}>通话中 {studyTime(second)}</p>
                  <button
                    style={{
                      background: 'red',
                    }}
                    onClick={async () => {
                      await leave_Live('end');
                      setsecond(0);
                    }}
                  >
                    挂断
                  </button>
                </div>
              )}
            </div>
            <div id="right_box">
              <h3 style={{ fontWeight: 'bolder' }}>预约列表</h3>
              <ProTable
                columns={invite_columns}
                request={async (params = {}) => get_invite_list()}
                rowKey={(record) => record.patient_id}
                search={false}
                toolBarRender={false}
                size="middle"
                pagination={{
                  pageSize: 8,
                  showSizeChanger: false,
                }}
                dateFormatter="string"
              />
              <h3 style={{ fontWeight: 'bolder', marginTop: '10px' }}>指导记录</h3>
              <TextArea
                style={{ height: '100%', resize: 'none' }}
                onChange={onChangecontent}
                rows={4}
                showCount
                maxLength={100}
                placeholder={'请填写指导记录'}
              />
            </div>
          </div>
        </>
      )}
    </PageContainer>
  );
};
export default RemoteVideo;
